package village.rainbow.slipin.uicontrol;

import village.rainbow.slipin.util.ScreenUtil;
import village.rainbow.slipin.util.ScreenUtil.ScreenRatioItem;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ActivityInfo;
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.graphics.Color;
import android.graphics.Typeface;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageButton;
import android.widget.RelativeLayout;
import android.widget.TextView;

public class ResizeLayout extends RelativeLayout
{
	private float mDestScreenW = 0.0f;
	private float mDestScreenH = 0.0f;
	private float mDestScreenRatioW = 0.0f;
	private float mDestScreenRatioH = 0.0f;
	private float mCaliScreenRatioW = 1.0f;
	private float mCaliScreenRatioH = 1.0f;
	private float mChildRatioW = 0.0f;
	private float mChildRatioH = 0.0f;
	private boolean mIsFullScreen = false;
	private OnSizeChangedCompleteListener mSizeChangedCompleteListener = null;
	
	public ResizeLayout(Context context)
	{
		super(context);
	}
	public ResizeLayout(Context context, AttributeSet attrs)
	{
		super(context, attrs);
	}
	public ResizeLayout(Context context, AttributeSet attrs, int defStyle)
	{
		super(context, attrs, defStyle);
	}
	
	/*
     * 넘어오는 파라메터는 부모뷰로부터 결정된 치수제한을 의미한다.
     * 또한 파라메터에는 bit 연산자를 사용해서 모드와 크기를 같이 담고있다.
     * 모드는 MeasureSpec.getMode(spec) 형태로 얻어오며 다음과 같은 3종류가 있다.
     *         MeasureSpec.AT_MOST : wrap_content (뷰 내부의 크기에 따라 크기가 달라짐)
     *         MeasureSpec.EXACTLY : fill_parent, match_parent (외부에서 이미 크기가 지정되었음)
     *      MeasureSpec.UNSPECIFIED : MODE 가 셋팅되지 않은 크기가 넘어올때 (대부분 이 경우는 없다)
     *  
     *   fill_parent, match_parent 를 사용하면 윗단에서 이미 크기가 계산되어 EXACTLY 로 넘어온다.
     *   이러한 크기는 MeasureSpec.getSize(spec) 으로 얻어낼 수 있다.
     *   
     *   이 메소드에서는 setMeasuredDimension(measuredWidth,measuredHeight) 를 호출해 주어야 하는데
     *   super.onMeasure() 에서는 기본으로 이를 기본으로 계산하는 함수를 포함하고 있다.
     *   
     *   만약 xml 에서 크기를 wrap_content 로 설정했다면 이 함수에서 크기를 계산해서 셋팅해 줘야한다.
     *   그렇지 않으면 무조껀 fill_parent 로 나오게 된다.
     *   
     *   [MesureSpec Mode]
     *   MeasureSpec.UNSPECIFIED:		// mode가 셋팅되지 않은 크기가 넘어올때
	 *   MeasureSpec.AT_MOST:			// wrap_content
	 *   MeasureSpec.EXACTLY:			// fill_parent or match_parent
     */
	@Override
	protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
	{
		if (mDestScreenW <= 0 || mDestScreenH <= 0)
		{
			setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
			super.onMeasure(widthMeasureSpec, heightMeasureSpec);	
			
			return;
		}
		
		int w = MeasureSpec.getSize(widthMeasureSpec);
		int h = MeasureSpec.getSize(heightMeasureSpec);		  
		
		// Fullscreen 모드가 아닐 때
		if (mIsFullScreen == false)
		{
			// 현재, 화면비율을 구한다.
			ScreenRatioItem ratioInfo = ScreenUtil.get().getScreenRatio(w, h);
			
			// 이미지 제작비율과 현재 화면 사이즈비율이 다를때
			if (ratioInfo.getRatiioW() != mDestScreenRatioW || ratioInfo.getRatiioH() != mDestScreenRatioH)
			{
				// 우선, 높이를 기준으로 맞춘다.
				float changeH = h;
				// 높이를 기준으로 넓이계산
				float changeW = (float)(changeH  / mDestScreenRatioH * mDestScreenRatioW); 
				// 구한 넓이를 화면 넓이와 비교해서 크다면 넓이를 기준으로 맞춘다.
				if (changeW > w)
				{
					// 넓이차를 구해서 높이에서 빼준다.
					float remainder = changeW - w;
					changeW = w;
					changeH = h - (remainder / mDestScreenRatioW * mDestScreenRatioH);
				}
				
				w = (int)changeW;
				h = (int)changeH;
			}
		}
			
		setMeasuredDimension(w, h);
		
		super.onMeasure(MeasureSpec.makeMeasureSpec(w, MeasureSpec.EXACTLY), 
				MeasureSpec.makeMeasureSpec(h, MeasureSpec.EXACTLY));
	}
	@Override
	protected void onSizeChanged(int w, int h, int oldw, int oldh)
	{
//		float buildRatioW = (float) (Build.MODEL.startsWith("BIOSTAR") ? 1.25 : 1);
//		float buildRatioH = (float) (Build.MODEL.startsWith("BIOSTAR") ? 0.9375 : 1);
		
		try{
			Activity parentActivity = (Activity)this.getContext();
			ActivityInfo actInfo = parentActivity.getPackageManager().getActivityInfo(parentActivity.getComponentName(), 
					PackageManager.GET_ACTIVITIES|PackageManager.GET_META_DATA);
			int actOri = actInfo.screenOrientation;
			int oriPortrait = Configuration.ORIENTATION_PORTRAIT;
			int oriLandScap = Configuration.ORIENTATION_LANDSCAPE;
			
			if(actOri == ActivityInfo.SCREEN_ORIENTATION_PORTRAIT && getResources().getConfiguration().orientation != oriPortrait){
				return;	
			}else if(actOri == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE && getResources().getConfiguration().orientation != oriLandScap){
				return;
			}
			
		}catch(Exception e){
			e.printStackTrace();
		}
		
		mChildRatioW = (float)(w * 1.0 / mDestScreenW * mCaliScreenRatioW);
		mChildRatioH = (float)(h * 1.0 / mDestScreenH * mCaliScreenRatioH);
		ScreenUtil.get().setChildRatioW(mChildRatioW);
		ScreenUtil.get().setChildRatioH(mChildRatioH);
		
		resizeChildSize(this, w, h, mChildRatioW, mChildRatioH);
		
		if (mSizeChangedCompleteListener != null)
			mSizeChangedCompleteListener.onSizeChangedComplete();
	}
	public void resizeChildSize(ViewGroup viewGroup, int parentW, int parentH) { resizeChildSize(viewGroup, parentW, parentH, mChildRatioW, mChildRatioH); }
	public void resizeChildSize(ViewGroup viewGroup, int parentW, int parentH, float childRatioW, float childRatioH)
	{
		// 부모뷰 Padding 설정
		viewGroup.setPadding((int)(viewGroup.getPaddingLeft() * childRatioW), 
				(int)(viewGroup.getPaddingTop() * childRatioH), 
				(int)(viewGroup.getPaddingRight() * childRatioW), 
				(int)(viewGroup.getPaddingBottom() * childRatioH));
		
		// 자식뷰 크기변환
		if (viewGroup.getChildCount() > -1)
		{
			boolean isRelativeLayout = false;
			
			if (viewGroup instanceof RelativeLayout)
				isRelativeLayout = true;
					
			for (int i = 0; i < viewGroup.getChildCount(); i++)
			{
				View child = viewGroup.getChildAt(i);
				
				if (child != null)
				{
					int childW = 0;
					int childH = 0;
					
					// ********************
					// Layout 별 설정
					
					boolean isCenterInParent = false, isCenterVertical = false, isCenterHorizontal = false;
					
					if (isRelativeLayout)
					{
						int[] rules = null;
						RelativeLayout.LayoutParams relParams = (RelativeLayout.LayoutParams)child.getLayoutParams();
						rules = relParams.getRules();
						
						if (rules != null)
						{
							for (int x = 0; x < rules.length; x++)
							{
								if (rules[x] == RelativeLayout.CENTER_IN_PARENT)
								{
									isCenterInParent = true;
									break;
								}
								else if (rules[x] == RelativeLayout.CENTER_VERTICAL)
								{
									isCenterVertical = true;
									
									if (isCenterHorizontal)
									{
										isCenterInParent = true;
										break;
									}
								}
								else if (rules[x] == RelativeLayout.CENTER_HORIZONTAL)
								{
									isCenterHorizontal = true;
									
									if (isCenterVertical)
									{
										isCenterInParent = true;
										break;
									}
								}
							}
						}
					}
					
					// ********************
					// 넓이, 높이 보정
					
					android.view.ViewGroup.LayoutParams params = child.getLayoutParams();
					
					// 넖이
					if (params.width == -1 || params.width == -2)	// fill_parent, match_parent
						childW = parentW;
					else
						childW = (int)(params.width * childRatioW + 0.5);
					if (childW > parentW)
						childW = parentW;
					// 높이
					if (params.height == -1 || params.height == -2)	// fill_parent, match_parent
						childH = parentH;
					else
						childH = (int)(params.height * childRatioH + 0.5);
					if (childH > parentH)
						childH = parentH;
						
					params.width = childW;
					params.height = childH;
					
					// ********************
					// 마진설정
					
					if (child.getLayoutParams() instanceof MarginLayoutParams)
					{
						MarginLayoutParams marginParams = (MarginLayoutParams)child.getLayoutParams();
						
						if (isCenterInParent)
						{
							marginParams.leftMargin = (int)(parentW * 0.5 + 0.5);
							marginParams.topMargin = (int)(parentH * 0.5 + 0.5);	
						}
						else if (isCenterVertical)
						{
							marginParams.leftMargin = (int)(marginParams.leftMargin * childRatioW + 0.5);
							marginParams.topMargin = (int)(parentH * 0.5 + 0.5);	
						}
						else if (isCenterHorizontal)
						{
							marginParams.leftMargin = (int)(parentW * 0.5 + 0.5);
							marginParams.topMargin = (int)(marginParams.topMargin * childRatioH + 0.5);	
						}
						else
						{
							marginParams.leftMargin = (int)(marginParams.leftMargin * childRatioW + 0.5);
							marginParams.topMargin = (int)(marginParams.topMargin * childRatioH + 0.5);	
						}
					}
					
					// ********************
					// TextView 설정
					
					// xml node android:translationX, translationY 에 대한 처리
					float tranX = child.getTranslationX();
					float tranY = child.getTranslationY();
					if (tranX != 0)
						child.setTranslationX((float) (child.getTranslationX()*childRatioW + 0.5));
					if (tranY != 0)
						child.setTranslationY((float) (child.getTranslationY()*childRatioH + 0.5));
					
					/*
					 * 위에꺼랑 같아서 주석처리함
					 * child.setX((float) (child.getX()*childRatioW + 0.5));
					 * child.setY((float) (child.getY()*childRatioH + 0.5));
					 */
					
					if (child instanceof Button || child instanceof TextView)
					{
						TextView textView = (TextView)child;
						textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, textView.getTextSize() * childRatioH);
						textView.setTypeface(Typeface.SERIF);
					}
					// Drawable 
					if (child instanceof Button || child instanceof ImageButton)
						setLayerDrawable(child);
					if (child instanceof ViewGroup)
						resizeChildSize((ViewGroup)child, childW, childH, childRatioW, childRatioH);
				}			
			}
		}
	}
	// 디폴트
	public void setLayerDrawable(View v)
	{
		createLayerDrawable(v, Color.parseColor("#809ec0ff"));
	}
	// #000000 형식으로 지정
	public void setLayerDrawable(View v, String color)
	{
		createLayerDrawable(v, Color.parseColor(color));
	}
	// Integer 값으로 지정
	public void setLayerDrawable(View v, int color)
	{
		createLayerDrawable(v, color);
	}
	@SuppressLint("NewApi")
	private void createLayerDrawable(View v, int color)
	{
		if (v == null)
			return;
		
		Drawable viewDrawable = v.getBackground();
		if (viewDrawable == null)
			viewDrawable = new ColorDrawable(Color.TRANSPARENT);
		ColorDrawable wrapDrawable = new ColorDrawable(color);
		Drawable[] layers = {viewDrawable, wrapDrawable};
		LayerDrawable layer = new LayerDrawable(layers);
		StateListDrawable stateDarwable = new StateListDrawable();
		
		stateDarwable.addState(new int[]{android.R.attr.state_pressed}, layer);
		stateDarwable.addState(new int[]{android.R.attr.state_focused}, layer);
		stateDarwable.addState(new int[]{}, viewDrawable);
		
		if (Build.VERSION.SDK_INT > 15)
			v.setBackground(stateDarwable);
		else
			v.setBackgroundDrawable(stateDarwable);
	}
//	public View[] createScrollBtns(int startID, int btnCount, int parentLayoutResID, int btnLayoutResID, int [] btnDimensionResID, 
//			OnClickListener clickListener, boolean isVertical)
//	{		
//		ViewGroup parentView = (ViewGroup)findViewById(parentLayoutResID);
//		
//		if (isVertical)
//		{
//			if (parentView == null || btnCount < 1 || btnDimensionResID.length < 6)
//				return null;
//		}
//		else
//		{
//			if (parentView == null || btnCount < 1 || btnDimensionResID.length < 5)
//				return null;
//		}
//		
//		View[] resultBtns = new View[btnCount];
//		Resources res = getContext().getResources();
//		LayoutInflater vi = (LayoutInflater)getContext().getApplicationContext()
//				.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
//		// 버튼 크기,마진, 부모레이아웃 padding 정보
//		int btnW = 0, btnH = 0, marginSideW = 0, marginSideH = 0, marginSpaceW = 0, marginSpaceH = 0;
//		
//		btnW = (int)(res.getDimension(btnDimensionResID[0]) * mChildRatioW);
//		btnH = (int)(res.getDimension(btnDimensionResID[1]) * mChildRatioH);
//		marginSideW = (int)(res.getDimension(btnDimensionResID[2]) * mChildRatioW);
//		marginSideH = (int)(res.getDimension(btnDimensionResID[3]) * mChildRatioH);
//		marginSpaceW = (int)(res.getDimension(btnDimensionResID[4]) * mChildRatioW);
//		
//		if (isVertical)
//			marginSpaceH = (int)(res.getDimension(btnDimensionResID[5]) * mChildRatioH);
//		
//		// 이번버튼들 삭제
//		parentView.removeAllViews();
//		// 부모 레이아웃 padding 설정
//		parentView.setPadding(marginSideW, marginSideH, marginSideW, marginSideH);
//		
//		// 테이블 버튼 생성
//		// 한줄에 차지하는 버튼개수 계산
//		int x = 0, y = 0, addCount = 0, lineBtnsNum = 0; 
//		
//		if (isVertical)
//		{
//			lineBtnsNum = parentView.getLayoutParams().width - (marginSideW * 2) + marginSpaceW;
//			lineBtnsNum /= btnW + marginSpaceW;
//		}
//		
//		while (addCount < btnCount)
//		{
//			View tableBtn = vi.inflate(btnLayoutResID, null);
//			RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(btnW, btnH);
//			
//			// 버튼 ID설정
//			tableBtn.setId(startID + addCount);
//			// 버튼 위치계산
//			params.leftMargin = x;
//			params.topMargin = y;
//			
//			if (isVertical)
//			{
//				if ((addCount + 1) % lineBtnsNum != 0)
//					x += btnW + marginSpaceW;
//				else
//				{
//					x = 0;
//					y += btnH + marginSpaceH;
//				}
//			}
//			else
//				x += btnW + marginSpaceW;
//			
//			// 버튼 add
//			if (clickListener != null)
//				tableBtn.setOnClickListener(clickListener);
//			tableBtn.setLayoutParams(params);
//			parentView.addView(tableBtn);
//			resultBtns[addCount] = tableBtn;
//			addCount++;
//		}
//		
//		return resultBtns;
//	}
	public void setOnSizeChangedCompleteListener(OnSizeChangedCompleteListener listener)
	{
		mSizeChangedCompleteListener = listener;
	}
	public void setDestScreenSize(int w, int h, boolean isFullScreen)
	{
		// 대상 화면 크기저장
		mDestScreenW = w;
		mDestScreenH = h;
		
		// Fullscreen 여부 저장
		mIsFullScreen = isFullScreen;
		
		// 화면비율 계산
		ScreenRatioItem ratioItem = ScreenUtil.get().getScreenRatio(w, h);
		
		mDestScreenRatioW = ratioItem.getRatiioW();
		mDestScreenRatioH = ratioItem.getRatiioH();		
	}	
	public void setDestScreenSize(int w, int h, int calibrationW, int calibrationH, boolean isFullScreen)
	{
		// 대상 화면 크기저장
		mDestScreenW = calibrationW;
		mDestScreenH = calibrationH;
		
		// Fullscreen 여부 저장
		mIsFullScreen = isFullScreen;
		
		// 화면비율 계산
		ScreenRatioItem ratioItem = ScreenUtil.get().getScreenRatio(calibrationW, calibrationH);
		mDestScreenRatioW = ratioItem.getRatiioW();
		mDestScreenRatioH = ratioItem.getRatiioH();
		// 보정비율 계산
		mCaliScreenRatioW = (float)((calibrationW * 1.0) / (w * 1.0));
		mCaliScreenRatioH = (float)((calibrationH * 1.0) / (h * 1.0));
	}	
	public int getDestScreenW() { return (int)mDestScreenW; }
	public int getDestScreenH() { return (int)mDestScreenH; }
	public float getDestScreenRatioW() { return mDestScreenRatioW; }
	public float getDestScreenRatioH() { return mDestScreenRatioH; }
	public float getChildRatioW() { return mChildRatioW; }
	public float getChildRatioH() { return mChildRatioH; }
}
